package cn.befory.tools;

import cn.befory.constants.UserConstants;
import cn.befory.exception.SysException;
import cn.befory.pojo.User;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static cn.befory.exception.ExceptionEnum.TOKEN_EXPIRE;


/**
 * @author befory
 * Created by DQ on 2018/4/9.
 */
@Component
public class JwtToken {
    /**
     * 密钥
     */
    private final static String SECRET = "befory";

    private final static String ALG = "alg";

    private final static String HS256 = "HS256";

    private final static String TYP = "typ";

    private final static String JWT_STR="JWT";
    /**
     * token过期时间
     */
    private final static int EXPIRES = 7200;
    /**
     * 签发时间
     */
    private Date issuedTime;
    /**
     *过期时间
     */
    private Date expiresTime;

    public Date setIssuedTime(Date d){
        return this.issuedTime = d;
    }

    public Date setExpiresTime(Date d){
        return this.expiresTime = d;
    }
    /**
     * 生成token
     * @return token
     * @throws Exception exception
     */
    public String createToken(User user) throws Exception{
        Calendar nowTime = Calendar.getInstance();
        Date issuedDate = nowTime.getTime();
        setIssuedTime(issuedDate);
        nowTime.add(Calendar.SECOND,EXPIRES);
        Date expiresDate = nowTime.getTime();
        setIssuedTime(expiresDate);
        Map<String,Object> map = new HashMap<String,Object>();
        map.put(ALG,HS256);
        map.put(TYP,JWT_STR);
        return JWT.create()
                .withHeader(map)
                .withClaim(UserConstants.USER_ID,String.valueOf(user.getId()))
                .withExpiresAt(expiresDate)
                .withIssuedAt(issuedDate)
                .sign(Algorithm.HMAC256(SECRET));
    }

    /**
     * 解密token
     * @param token token
     * @return claim
     * @throws Exception exception
     */
    public Map<String,Claim> verifyToken(String token) throws Exception{
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
        DecodedJWT decodedJWT = jwtVerifier.verify(token);
        return decodedJWT.getClaims();
    }

    public Long getUserId(String token){
        try {
            Map<String, Claim> stringClaimMap = verifyToken(token);
            return Long.valueOf(stringClaimMap.get(UserConstants.USER_ID).asString());
        }catch (Exception e){
            throw new SysException(TOKEN_EXPIRE);
        }
    }


    public static int getExpires() {
        return EXPIRES;
    }

    public long getIssuedTime(){
        return this.issuedTime.getTime();
    }

    public static void main(String[] args) throws Exception {
//        User userInfo = new User();
//        String token = new JwtToken().createToken(userInfo);
//        System.out.println(token);
        String tokenExpire = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiMyIsImV4cCI6MTU1MTIwMzkwNiwiaWF0IjoxNTUxMTk2NzA2fQ.ubEdvjN-dwMG5d_0OiNGLlbeugFR0XFvSmqcT_v7fi0";
        Map<String,Claim> map = new JwtToken().verifyToken(tokenExpire);
        System.out.println(map.get("user_id").asString());
//        Map<String,Claim> map1 = JwtToken.verifyToken(tokenExpire);

    }
}
